﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.LIB;
using YJKOpeningCommon.DataEnum;
using YJKOpeningCommon.Public;
using YJKOpeningDesignInput.ConfigForm;
using YJKOpeningDesignInput.Public;

namespace YJKOpeningDesignInput.EquipCollector
{
	public class EquipMentCollector
	{
		public EquipMentCollector(Autodesk.Revit.DB.Document doc)
		{
			this.m_doc = doc;
			this.m_lstRevitLinkIns = CommonInterface.GetLinkRevitIns(doc);
			this.m_lstEquipData = new List<EquipData>();
			this.ReadEquipCollectorXml();
		}

		public void GetEquips(ref MEPData mepData, OpeningSelectForm openingSelectForm, ExternalCommandData cmdData, PickedBox pickedBox)
		{
			this.GetEquip(ref mepData, this.m_doc, null, openingSelectForm, cmdData, pickedBox);
			foreach (RevitLinkInstance revitLinkInstance in this.m_lstRevitLinkIns)
			{
				Document linkDocument = revitLinkInstance.GetLinkDocument();
				if (linkDocument != null)
				{
					this.GetEquip(ref mepData, linkDocument, revitLinkInstance, openingSelectForm, cmdData, pickedBox);
				}
			}
		}

		private void GetEquip(ref MEPData mepData, Autodesk.Revit.DB.Document doc, RevitLinkInstance revitLinkIns, OpeningSelectForm openingSelectForm, ExternalCommandData cmdData, PickedBox pickedBox)
		{
			string empty = string.Empty;
			foreach (EquipData equipData in this.m_lstEquipData)
			{
				string strPattern = equipData.m_strPattern;
				FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
				filteredElementCollector.OfCategory(equipData.m_category).WhereElementIsNotElementType();
				filteredElementCollector = this.SelectMode(openingSelectForm, cmdData, doc, filteredElementCollector, this.GetHight(cmdData), pickedBox);
				foreach (Element element in filteredElementCollector)
				{
					FamilyInstance familyInstance = element as FamilyInstance;
					if (familyInstance != null && Regex.IsMatch(this.GetStrFamilyName(familyInstance), strPattern))
					{
						string strFiName = equipData.m_strFiName;
						EEquipType equipType;
						if (!(strFiName == "消火栓"))
						{
							if (!(strFiName == "电气设备") && !(strFiName == "通讯设备") && !(strFiName == "火警设备"))
							{
								if (!(strFiName == "分集水器"))
								{
									continue;
								}
								equipType = EEquipType.eWaterCollectorEquipment;
							}
							else
							{
								equipType = EEquipType.eElectricalEquipment;
							}
						}
						else
						{
							equipType = EEquipType.eMechanicalEquipment;
						}
						StructFiBindingData value = new StructFiBindingData(equipType, revitLinkIns);
						mepData.m_dictionaryEquip.Add(familyInstance, value);
					}
				}
			}
		}

		private double GetHight(ExternalCommandData cmdData)
		{
			List<double> level = Common.GetLevel(cmdData.Application.ActiveUIDocument.Document);
			int num = level.IndexOf(cmdData.Application.ActiveUIDocument.Document.ActiveView.GenLevel.Elevation);
			double result;
			if (num < level.Count - 1)
			{
				result = level[num + 1] - level[num];
			}
			else
			{
				result = 13.0;
			}
			return result;
		}

		private FilteredElementCollector SelectMode(OpeningSelectForm openingSelectForm, ExternalCommandData cmdData, Autodesk.Revit.DB.Document doc, FilteredElementCollector collector, double height, PickedBox pickedBox)
		{
			if (openingSelectForm.IsSelectBox)
			{
				BoundingBoxXYZ boundingBoxXYZ = new BoundingBoxXYZ();
				boundingBoxXYZ.Max = pickedBox.Max;
				boundingBoxXYZ.Min = pickedBox.Min;
				double num = 0.0;
				double num2 = 0.0;
				double num3 = 0.0;
				double num4 = 0.0;
				this.CheckMaxXY(boundingBoxXYZ, ref num, ref num2, ref num3, ref num4);
				boundingBoxXYZ.Max = new XYZ(num, num2, 0.0);
				boundingBoxXYZ.Min = new XYZ(num3, num4, 0.0);
				collector = SolidFilter.GetIntersectsSolid(cmdData.Application.ActiveUIDocument.Document, SolidFilter.CreateSolid(cmdData.Application.ActiveUIDocument.Document, boundingBoxXYZ, height, cmdData.Application.ActiveUIDocument.Document.ActiveView.GenLevel.Elevation), collector);
			}
			if (openingSelectForm.IsSelectLevel)
			{
				BoundingBoxXYZ cropBox = cmdData.Application.ActiveUIDocument.Document.ActiveView.CropBox;
				double num5 = 1000000.0;
				double num6 = 1000000.0;
				double num7 = -1000000.0;
				double num8 = -1000000.0;
				cropBox.Max = new XYZ(num5, num6, 0.0);
				cropBox.Min = new XYZ(num7, num8, 0.0);
				collector = SolidFilter.GetIntersectsSolid(cmdData.Application.ActiveUIDocument.Document, SolidFilter.CreateSolid(cmdData.Application.ActiveUIDocument.Document, cropBox, height, cmdData.Application.ActiveUIDocument.Document.ActiveView.GenLevel.Elevation), collector);
			}
			return collector;
		}

		private void CheckMaxXY(BoundingBoxXYZ boundingBoxXYZref, ref double maxX, ref double maxY, ref double minX, ref double minY)
		{
			if (boundingBoxXYZref.Max.X > boundingBoxXYZref.Min.X)
			{
				maxX = boundingBoxXYZref.Max.X;
				minX = boundingBoxXYZref.Min.X;
			}
			else
			{
				minX = boundingBoxXYZref.Max.X;
				maxX = boundingBoxXYZref.Min.X;
			}
			if (boundingBoxXYZref.Max.Y > boundingBoxXYZref.Min.Y)
			{
				maxY = boundingBoxXYZref.Max.Y;
				minY = boundingBoxXYZref.Min.Y;
				return;
			}
			minY = boundingBoxXYZref.Max.Y;
			maxY = boundingBoxXYZref.Min.Y;
		}

		private bool ReadEquipCollectorXml()
		{
			string text = Product.DataLocation + "\\EquipCollector.xml";
			if (!File.Exists(text))
			{
				return false;
			}
			XmlReader xmlReader = null;
			try
			{
				XmlDocument xmlDocument = new XmlDocument();
				xmlReader = XmlReader.Create(text, new XmlReaderSettings
				{
					IgnoreComments = true
				});
				xmlDocument.Load(xmlReader);
				foreach (object obj in xmlDocument.SelectSingleNode("DataItems").ChildNodes)
				{
					XmlNode xmlNode = (XmlNode)obj;
					string value = xmlNode.Attributes["Category"].Value;
                    BuiltInCategory category = (BuiltInCategory)Convert.ToInt32(value);
					string value2 = xmlNode.Attributes["StrKeyword"].Value;
					string value3 = xmlNode.Attributes["StrFamilyName"].Value;
					EquipData equipData = new EquipData(category, value2, value3);
					if (equipData == null)
					{
						YJKMessageBox.Show("读取EquipCollectorXml文件异常：Category=" + value);
					}
					else
					{
						this.m_lstEquipData.Add(equipData);
					}
				}
			}
			catch (Exception)
			{
				if (xmlReader != null)
				{
					xmlReader.Close();
					xmlReader = null;
				}
				YJKMessageBox.Show("读取EquipCollectorXml文件异常");
			}
			if (xmlReader != null)
			{
				xmlReader.Close();
			}
			return true;
		}

		private string GetStrFamilyName(FamilyInstance fiIns)
		{
			if (fiIns == null)
			{
				return "";
			}
			FamilySymbol symbol = fiIns.Symbol;
			if (symbol == null)
			{
				return "";
			}
			Family family = symbol.Family;
			if (family == null)
			{
				return "";
			}
			return family.Name;
		}

		private Document m_doc;

		private List<EquipData> m_lstEquipData;

		private List<RevitLinkInstance> m_lstRevitLinkIns;
	}
}
